package com.hitqz.robot.biz.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.hitqz.robot.api.common.dto.file.UploadFileVo;
import com.hitqz.robot.biz.core.FileProperties;
import com.hitqz.robot.biz.util.CommonFileUtil;
import com.hitqz.robot.common.core.util.R;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author xupkun
 * @date 2024/6/4
 */

@RestController
@AllArgsConstructor
@RequestMapping("/")
@Tag(name = "机器人文件管理")
@Slf4j
public class FileController {

    private final FileProperties fileProperties;


    public static final ThreadPoolExecutor networkExecutor = new ThreadPoolExecutor(
            10,               // 核心线程数
            20,              // 最大线程数
            60L,             // 非核心线程存活时间
            TimeUnit.SECONDS, // 时间单位
            new LinkedBlockingQueue<>(50),  // 阻塞队列
            Executors.defaultThreadFactory(), // 默认的线程工厂
            new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略：提交任务的线程执行任务
    );
    @GetMapping("/file/**")
    public ResponseEntity<byte[]> download(HttpServletRequest request) throws UnsupportedEncodingException {
        String fullPath = request.getRequestURI();
        //计算路径相对于 /file 的部分
        String relativePath = fullPath.substring(fullPath.indexOf("/file") + "/file".length());
        // 对路径进行 URL 解码，确保中文字符正确显示
        relativePath = URLDecoder.decode(relativePath, StandardCharsets.UTF_8);
        Path path = Paths.get(fileProperties.getLocal().getBasePath(), relativePath).normalize();
        return downloadFile(path.toFile());
    }






    public ResponseEntity<byte[]> downloadFile(File file) {
        try {
            if (!file.exists()) {
                log.warn("[file]no exist:{}",file.getAbsolutePath());
                return ResponseEntity.notFound().build();
            }
            // 获取文件扩展名
            String fileName = file.getName();
            // 根据扩展名确定媒体类型
            String mediaType = Files.probeContentType(file.toPath());
            if (mediaType == null) {
                mediaType = MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE; // 默认为二进制流
            }
            FileInputStream in = new FileInputStream(file);
            byte[] fileBytes = in.readAllBytes();
            in.close();
            HttpHeaders headers = new HttpHeaders();
            headers.set(HttpHeaders.CONTENT_TYPE, mediaType);
            headers.setContentLength(fileBytes.length);
            if (fileName.contains(".xlsx")) {
                headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
            }
            return new ResponseEntity<>(fileBytes, headers, HttpStatus.OK);
        }catch (Exception e){
            log.info("[file] download {},error:{}",file.getAbsolutePath(), e.getMessage());
            return ResponseEntity.notFound().build();
        }
    }


    @PostMapping(value = "/upload")
    @Parameter(name = "files", required = true)
    public R<UploadFileVo> upload(@RequestPart("file") MultipartFile files) {
        if(files.isEmpty()) {
            return R.failed("请上传文件");
        }
        UploadFileVo vo = new UploadFileVo();
        String dir =fileProperties.getLocal().getBasePath();
        log.info("[upload] upload");
        if (StrUtil.isEmpty(dir)) {
            return R.failed("未进行配置上传目录");
        }
        String fileName = files.getOriginalFilename();
        File file = new File(dir + File.separator +  "upload" + File.separator + fileName);
        try {
            FileUtil.writeBytes(files.getBytes(), file);
        } catch (Exception e) {
            log.info("保存文件失败");
        }
        return R.ok();
    }



    @GetMapping(value = "downLogs")
    public ResponseEntity<Resource> downloadLogs() {
        File targetLogFile = new File(CommonFileUtil.zipLogFile());
        if (targetLogFile.exists()) {
            HttpHeaders headers = new HttpHeaders();
            headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
            headers.add("Pragma", "no-cache");
            headers.add("Expires", "0");
            headers.add("Content-Disposition", "attachment; filename=\"log.zip\"");
            FileSystemResource resource = new FileSystemResource(targetLogFile);
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(targetLogFile.length())
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(resource);
        }
        return ResponseEntity.notFound().build();
    }




}
